﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using System.Diagnostics;
using System.IO.Pipes;
using System.Security.Principal;
using System.Threading;

namespace EtlComm
{
    public delegate void UpdateLog(string StationID, string StationName, string TaskID, DispatchProcess dpStatus, bool IsUpdated);

    public class SynXML:IDisposable
    {
        private XElement _XEStation = null;
        private int _SaveCount = 0;
        

        /// <summary>
        /// 构造函数
        /// </summary>
        public SynXML()
        {
            _XEStation = XElement.Load(EtlGlobal.XmlStationFile);
        }

        ~SynXML()
        {
            Dispose(false);
            //Save();
        }

        /// <summary>
        /// 取开始标志值
        /// </summary>
        /// <param name="StationID">加油站ID</param>
        /// <param name="TaskID">任务ID</param>
        /// <returns>值</returns>
        /// 线程安全
        public string GetStartFromXML(string StationID, string TaskID)
        {
            string endDateTime;
            lock (LockObject.XmlFileLock)
            {
                Debug.Assert(_XEStation != null);
                var record = (from a in _XEStation.Descendants("Station")
                              where a.Element("StationID").Value == StationID
                              select a).FirstOrDefault();
                var element = (from a in record.Descendants("TaskInfo")
                               where a.Element("TaskID").Value == TaskID
                               select a).FirstOrDefault();
                endDateTime = (element.Element("StartTime").Value);
            }

            return endDateTime;
        }
        /// <summary>
        /// 取结束标志值
        /// </summary>
        /// <param name="StationID">加油站ID</param>
        /// <param name="TaskID">任务ID</param>
        /// <returns>值</returns>
        /// 线程安全
        public string GetEndFromXML(string StationID, string TaskID)
        {
            string endDateTime;
            lock (LockObject.XmlFileLock)
            {
                Debug.Assert(_XEStation != null);
                var record = (from a in _XEStation.Descendants("Station")
                              where a.Element("StationID").Value == StationID
                              select a).FirstOrDefault();
                var element = (from a in record.Descendants("TaskInfo")
                               where a.Element("TaskID").Value == TaskID
                               select a).FirstOrDefault();
                endDateTime = (element.Element("EndTime").Value);
            }

            return endDateTime;
        }

        /// <summary>
        /// 更新任务时间配置
        /// </summary>
        /// <param name="IsSucceed">任务是否执行成功</param>
        /// <param name="stationRule">加油站信息</param>
        /// <param name="task">任务信息</param>
        /// 线程安全
        public void UpdateSQLParam(bool IsSucceed, StationInfo stationRule, TaskObject task)
        {
            Debug.Assert(_XEStation != null);
            //要更新的数据
            UpdateData UD = new UpdateData();
            UD.StationID = stationRule.StationID;
            UD.TaskID = task.TaskID.ToString();
            UD.ExeTime = "10";
            
            XElement element = null;
            if (IsSucceed)
            {
                lock (LockObject.XmlFileLock)
                {
                    var record = (from a in _XEStation.Descendants("Station")
                                  where a.Element("StationID").Value == stationRule.StationID
                                  select a).FirstOrDefault();
                    element = (from a in record.Descendants("TaskInfo")
                                   where a.Element("TaskID").Value == task.TaskID.ToString()
                                   select a).FirstOrDefault();
                }
                
                switch (task.ParamType)
                {
                    case StepType.DATETIME:
                        DateTime endDateTime = DateTime.Parse(element.Element("EndTime").Value).AddMinutes(task.Step);
                        //抽取时间是否超过了当前系统时间
                        if (endDateTime >= task.DBTime)
                            return;
                        //更新时间参数
                        if (task.HasParams)
                        {
                            task.ParamsStart = DateTime.Parse(element.Element("EndTime").Value);
                            task.ParamsEnd = DateTime.Parse(element.Element("EndTime").Value).AddMinutes(task.Step);
                            UD.BeginParam = DateTime.Parse(task.ParamsStart.ToString()).ToString("yyyy-MM-dd HH:mm:ss");
                            UD.EndParam = DateTime.Parse(task.ParamsEnd.ToString()).ToString("yyyy-MM-dd HH:mm:ss");
                            lock (LockObject.XmlFileLock)
                            {
                                element.SetElementValue("StartTime", DateTime.Parse(task.ParamsStart.ToString()).ToString("yyyy-MM-dd HH:mm:ss"));
                                element.SetElementValue("EndTime", DateTime.Parse(task.ParamsEnd.ToString()).ToString("yyyy-MM-dd HH:mm:ss"));
                            }
                            Save(UD);
                        }
                        break;
                    case StepType.INT:
                        //抽取ID是否超过了当前最大ID
                        if (0 == task.ResultMaxID)
                            task.ResultMaxID = int.Parse(element.Element("EndTime").Value);
                        //更新参数
                        if (task.HasParams)
                        {
                            task.ParamsStart = task.ResultMaxID + 1;
                            task.ParamsEnd = task.ResultMaxID + task.Step;
                            UD.BeginParam = task.ParamsStart.ToString();
                            UD.EndParam = task.ParamsEnd.ToString();
                            lock (LockObject.XmlFileLock)
                            {
                                element.SetElementValue("StartTime", task.ParamsStart.ToString());
                                element.SetElementValue("EndTime", task.ParamsEnd.ToString());
                            }
                            Save(UD);
                        }
                        break;
                }
                UpdateLog temp = OnUpdateLog;
                if (temp != null)
                {
                    temp(stationRule.StationID, stationRule.StationName, task.TaskID.ToString(), DispatchProcess.COMPLETED, true);
                }

            }
            else
            {
                UpdateLog temp = OnUpdateLog;
                if (temp != null)
                {
                    temp(stationRule.StationID, stationRule.StationName, task.TaskID.ToString(), DispatchProcess.FAIL, false);
                }
            }
        }

        private void Save(UpdateData UD)
        {
            //由自己更新XML
            if (EtlGlobal.XmlSave.Equals("local",StringComparison.CurrentCultureIgnoreCase))
            {
                Save();
                return;
            }
            //由监控更新XML
            try
            {
                EtlGlobal.sk.WaitOne();
                NamedPipeClientStream pipeClient =
                        new NamedPipeClientStream(".", "sunjunwu",
                            PipeDirection.InOut, PipeOptions.None,
                            TokenImpersonationLevel.Impersonation);
                try
                {
                    pipeClient.Connect(1000 * 30);
                }
                catch (TimeoutException e)
                {
                    Debug.WriteLine(e.ToString());
                    return;
                }
                Debug.WriteLine(string.Format("找到{0}个命名管道服务实例.", pipeClient.NumberOfServerInstances));
                EtlStreamString ss = new EtlStreamString(pipeClient);
                if (ss.ReadString() == "SERVER READY")
                {
                    ss.WriteString(UD.ToString());
                }
                pipeClient.Close();
            }
            catch (System.Exception ex)
            {
                Debug.WriteLine(ex.ToString());
            }
            finally
            {
                EtlGlobal.sk.Release();
            }
        }
        //更新完成XML事件
        public UpdateLog OnUpdateLog;

        /// <summary>
        /// 保存更新数据
        /// </summary>
        private void Save()
        {
            lock (LockObject.XmlFileLock)
            {
                if (_SaveCount++ >= EtlGlobal.XmlIoSaveCount)
                {
                    _XEStation.Save(EtlGlobal.XmlStationFile);
                    _SaveCount = 0;
                }
            }
        }

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        protected virtual void Dispose(bool disposing)
        {
            if (disposing)
            {

            }
            else
            {
                _SaveCount = 101;
            }
        }
    }
}
